package cn.jolyoulu.common.core.utils.other;


import javax.sound.sampled.*;
import java.io.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author: JolyouLu
 * @Date: 2025/9/3 18:59
 * @Version 1.0
 * 音频处理工具类
 */
public class WavUtils {

    /**
     * 切割音频
     * @param file 文件
     * @param startTime 哪里开始切
     * @param duration 持续多少
     * @param os 切好的文件流
     * @throws Exception
     */
    public static void cutAudio(File file, long startTime, long duration, TimeUnit timeUnit, OutputStream os) throws Exception {
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(bis)) {
            cutAudio(audioInputStream,startTime,duration,timeUnit,os);
        }
    }

    /**
     * 切割音频
     * @param audioInputStream 音频流
     * @param startTime 哪里开始切
     * @param duration 持续多少
     * @param timeUnit 时间单位
     * @param os 切好的文件流
     * @throws Exception
     */
    public static void cutAudio(AudioInputStream audioInputStream, long startTime, long duration, TimeUnit timeUnit, OutputStream os) throws Exception {
        AudioFormat format = audioInputStream.getFormat();
        double sampleRate = format.getSampleRate(); //采样率（样本/秒）
        long frameSize = format.getFrameSize();     //每个帧的字节数
        //跳过部分数据
        long startFrame = (long) ((timeUnit.toMillis(startTime) / 1000.0) * sampleRate);
        long bytesToSkip = startFrame * frameSize;
        long actualSkipped = audioInputStream.skip(bytesToSkip);
        if (actualSkipped != bytesToSkip) {
            throw new IOException("跳过音频数据失败，实际跳过：" + actualSkipped + " 字节，期望：" + bytesToSkip);
        }
        //截取多长的音频
        long framesToRead = (long) ((timeUnit.toMillis(duration) / 1000.0) * sampleRate);
        AudioInputStream shortenedStream = new AudioInputStream(audioInputStream,format, framesToRead);
        AudioSystem.write(shortenedStream, AudioFileFormat.Type.WAVE, os);
    }

}
